package org.nebuloop.photo.organizer.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;

/**
 * Similar to Java Standard Console Format but outputs the entire message in as
 * single line.
 */
public class SimpleFormatter extends Formatter {

  Date dat = new Date();
  private final MessageFormat formatter = new MessageFormat("{0,date,yyyy-MM-dd} {0,time,HH:mm:ss,SSS}");
  private final Object args[] = new Object[1];
  private static final String infoSeparator = "\t";
  private static final String lineSeparator = System.getProperty("line.separator");

  /**
   * Format the given LogRecord.
   * 
   * @param record
   *          the log record to be formatted.
   * @return a formatted log record
   */
  @Override
  public synchronized String format(LogRecord record) {
    StringBuilder sb = new StringBuilder();
    // Minimize memory allocations here.
    dat.setTime(record.getMillis());
    args[0] = dat;
    StringBuffer text = new StringBuffer();
    // if (formatter == null) {
    // formatter =
    // }
    formatter.format(args, text, null);
    sb.append(text);
    sb.append(" ");
    if (record.getSourceClassName() != null) {
      sb.append(record.getSourceClassName());
    } else {
      sb.append(record.getLoggerName());
    }
    if (record.getSourceMethodName() != null) {
      sb.append(" ");
      sb.append(record.getSourceMethodName());
    }
    sb.append(infoSeparator);
    String message = formatMessage(record);
    sb.append(record.getLevel().getLocalizedName());
    sb.append(": ");
    sb.append(message);
    sb.append(lineSeparator);
    if (record.getThrown() != null) {
      try {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        record.getThrown().printStackTrace(pw);
        pw.close();
        sb.append(sw.toString());
      } catch (Exception ex) {
        // ignore...don't expect error in StringWriter
      }
    }
    return sb.toString();
  }
}
